<?php
/**
 * $Id: RPC2.php 436 2006-07-21 11:09:48Z tito $
 *
 * FGS is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

// lib
require_once('api/fgs.php');
require_once('api/xmlrpc.class.php');

fgs::init();
/**
global $HTTP_RAW_POST_DATA;
if (!$HTTP_RAW_POST_DATA) {
   die('XML-RPC server accepts POST requests only.');
}
else
{
	$f = @fopen('/tmp/debugrpc.log', 'a');
	if ($f) {
		@fwrite($f, $HTTP_RAW_POST_DATA);
		@fclose($f);
	}
}
/**/

//============================================================

// {{{ method : news.getcategorylist()
function news_getcategorylist($args)
{
	// check parameter count
	if (count($args) != 0)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// fetch categories
	$cats = array();
	$rows = fgsNews::getCategories();
	foreach ($rows as $row) {
		$cats[] = array(
			'category_id'        => $row['id'],
			'category_name'      => $row['name'],
			'category_logo_hash' => $row['logo_hash']
		);
	}

	return $cats;
}
// }}}

// {{{ method : news.getnewslist()
// param 0 : news count, max to 30
// param 1 : category (optional)
function news_getnewslist($args)
{
	// check parameter count
	if ((count($args) < 1) && (count($args) > 3))
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// maximum items count : 30
	if ($args[0] > 30)
		$args[0] = 30;

	// fetch news
	$rows = fgsNews::getLast($args[2], $args[0], $args[1]);
	$news = array();
	if (is_array($rows)) {
		foreach ($rows as $row) {
			$news[] = array(
				'news_id'       => $row['id'],
				'news_category' => $row['category'],
				'news_title'    => $row['title'],
				'news_subtitle' => $row['subtitle'],
				'news_author'   => $row['login'],
				'news_date'     => $row['dt_create'],
				'news_lang'     => $row['lang']
			);	
		}
	}
	return $news;
}
// }}}

// {{{ method : news.getcategorylogo()
// param 0 : logo hash
function news_getcategorylogo($args)
{
	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40013, 'W3_InvalidHash');

	// get logo
	fgsLog::log(0, sprintf('Requested category logo, hash: "%s"', $args[0]));
	$logo = fgsNews::getLogo($args[0]);
	if (!$logo)	
		return new IXR_Error(-40013, 'W3_InvalidHash');

	return array('logo' => $row['logo_data']);
}
// }}}

// {{{ method : news.getnewsitem()
// param 0 : id
function news_getnewsitem($args)
{
	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// fetch news
	$news = fgsNews::getHtml($args[0]);
	if (!$news)
		return new IXR_Error(-40014, 'W3_InvalidId');

	return array('text' => $news);
}
// }}}

// {{{ method : user.login()
// param 0 : login
// param 1 : pass
function user_login($args)
{
	// check parameter count
	if (count($args) != 2)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[1]))
		return new IXR_Error(-40005, 'W3_InvalidPassword');

	// connect to the database
	if (!fgsUsers::checkLogin($args[0], md5($args[1])))
		return new IXR_Error(-40006, 'W3_IdentificationFailed');

	// add session into database
	$user_sid = fgsUsers::createSession($args[0], $user_sid);
	fgsLog::log(0, sprintf('user "%s" logged', $args[0]));

	return $user_sid;
}
// }}}

// {{{ method : user.logout()
// param 0 : login
// param 1 : user_sid
function user_logout($args)
{
	// check parameter count
	if (count($args) != 2)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[1]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');

	// add session into database
	$res = fgsUsers::deleteSession($args[0], $args[1]);
	if ($res > 0) 
		return true;

	return new IXR_Error(-40008, 'W3_InvalidSession');
}
// }}}

// {{{ method : user.info()
// param 0 : login
function user_info($args)
{
	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');

	// search info
	$infos = fgsUsers::get($args[0]);
	if (!$infos)
		return new IXR_Error(-40004, 'W3_InvalidUser');

	$login = $infos['login'];
	$infos['matchCount'] = fgsStats::getPlayerMatchCount($login, true);

	$stats2 = fgsStats::getPlayersScores(true);
	$stats = array();
	foreach ($stats2 as $gid=>$values)
		if (isset($values[$login]))
			$stats[$gid] = $values[$login];

	$infos['games'] = $stats;
	unset($infos['password']);
	
	return $infos;
}
// }}}

// {{{ method : user.getgamelogo()
// param 0 : logo hash
function user_getgamelogo($args)
{
	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	fgsLog::log(0, sprintf('Requested game logo, hash: "%s"', $args[0]));
	$data = fgsGames::getLogo($args[0]);
	if (!$data)
		return new IXR_Error(-40100, 'W3_InvalidHash');

	return array('logo' => $data['logo_data']);
}
// }}}

// {{{ method : user.getgamelist()
function user_getgamelist($args)
{
	// check parameter count
	if (count($args) != 0)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	$rows = fgsGames::get(null, true);
	$games = array();	
	foreach ($rows as $row) {
		$games[] = array(
			'game_id'     => $row['gid'],
			'game_name'   => $row['name'],
			'game_desc'   => $row['description'],
			'game_url'    => $row['url'],
			'logo_hash'   => $row['logo_hash'],
			'port'        => (int)$row['port']
		);
	}

	return $games;
}
// }}}

// {{{ method : user.getserverlist()
// param 0 : name of game (bzflag, wesnoth...)
function user_getserverlist($args)
{
	global $config;

	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40002, 'W3_InvalidGame');

	// check that game exist
	if (!fgsGames::exist($args[0]))
		return new IXR_Error(-40003, 'W3_UnknownGame');

	// fetch servers list
	$rows = fgsGames::getServers($args[0]);
	foreach ($rows as $row) {
		$servers[] = array(
			'game_name' => $row['game_name'],
			'game_version' => $row['game_version'],
			'host' => $row['host'],
			'port' => (int)$row['port'],
			'fgs' => $row['fgs']
		);
	}

	return $servers;
}
// }}}

// {{{ method : fgsd.register()
// param 0 : key
// param 1 : password
// param 2 : server_timestamp
function fgsd_register($args)
{
	// check parameter count
	if (count($args) != 3)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40010, 'W3_InvalidServerKey');
	if (empty($args[1]))
		return new IXR_Error(-40009, 'W3_InvalidServerPassword');
	if ((int)$args[2] <= 0)
		return new IXR_Error(-40000, 'W3_InvalidTimestamp');

	// register and return sid
	$fgsd_sid = fgsProxys::register($args[0], $args[1]);
	if (false === $fgsd_sid) 
		return new IXR_Error(-40000, 'W3_Unauthorized');

	return $fgsd_sid;
}
// }}}

// {{{ method : fgsd.unregister()
// param 0 : fgsd_sid
function fgsd_unregister($args)
{
	// check parameter count
	if (count($args) != 1)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');

	// register and return sid
	$fgsd_sid = fgsProxys::unregister($args[0]);
	if (false === $fgsd_sid) 
		return new IXR_Error(-40000, 'W3_Unauthorized');

	return true;
}
// }}}

// {{{ method : fgsd.ping()
// param 0 : fgsd_sid
// param 1 : server_timestamp
function fgsd_ping($args)
{
	fgsLog::log(1, 'method fgsd.ping');

	// check parameter count
	if (count($args) != 2)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40010, 'W3_InvalidServerKey');
	if ((int)$args[1] <= 0)
		return new IXR_Error(-40000, 'W3_InvalidTimestamp');

	// unregister
	$fgsd_sid = fgsProxys::ping($args[0], $args[1]);
	if ($fgsd_sid === false) 
		return new IXR_Error(-40000, 'W3_Unauthorized');

	return true;
}
// }}}

// {{{ method : fgsd.user.verify()
// param 0 : fgsd_sid
// param 1 : user_id
// param 2 : user_sid
function fgsd_user_verify($args)
{
	// check parameter count
	if (count($args) != 4)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[2]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[3]) || strlen($args[3]) != 16)
		return new IXR_Error(-40008, 'W3_InvalidSalt');

	// check proxy session
	if (false === fgsProxys::checkSession($args[0]))
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// check user session
	if (false === fgsUsers::checkSession($args[1], $args[2], $args[3]))
		return new IXR_Error(-40006, 'W3_SessionNotFound');

	return true;
}
// }}}

// {{{ method : fgsd.user.join()
// param 0 : fgsd_sid
// param 1 : fgsd_game_sid
// param 2 : user_login
// param 3 : user_sid
// param 4 : salt
function fgsd_user_join($args)
{
	// check parameter count
	if (count($args) != 5)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[2]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[3]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[4]) || strlen($args[4]) != 16)
		return new IXR_Error(-40008, 'W3_InvalidSalt');

	// check proxy session
	if (false === fgsProxys::checkSession($args[0]))
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// check match session
	$fgsd_games = fgsMatchs::checkSession($args[1]);
	if (false === $fgsd_games)
		return new IXR_Error(-40006, 'W3_SessionNotFound');

	// set user session to current fgsd
	fgsUsers::setCurrentMatch($fgsd_games['id'], $args[2], $args[3], $args[4]);

	return true;
}
// }}}

// {{{ method : fgsd.user.leave()
// param 0 : fgsd_sid
// param 1 : fgsd_game_sid
// param 2 : user_login
// param 3 : user_sid
// param 4 : salt
function fgsd_user_leave($args)
{
	// check parameter count
	if (count($args) != 5)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[2]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[3]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[4]) || strlen($args[4]) != 16)
		return new IXR_Error(-40008, 'W3_InvalidSalt');

	// check proxy session
	if (false === fgsProxys::checkSession($args[0]))
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// check match session
	if (false === fgsMatchs::checkSession($args[1]))
		return new IXR_Error(-40006, 'W3_SessionNotFound');

	// set user session to current fgsd
	fgsUsers::setCurrentMatch(null, $args[2], $args[3], $args[4]);

	return true;
}
// }}}

// {{{ method : fgsd.user.update()
// param 0 : fgsd_sid
// param 1 : user_login
// param 2 : user_sid
// param 3 : salt
// param 4 : array of key/values
// param 5 : timestamp
function fgsd_user_update($args)
{
	// check parameter count
	if (count($args) != 6)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40004, 'W3_InvalidLogin');
	if (empty($args[2]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[3]) || strlen($args[3]) != 16)
		return new IXR_Error(-40008, 'W3_InvalidSalt');
	if (!is_array($args[4]))
		return new IXR_Error(-40014, 'W3_InvalidPlayersValues');
	if ((int)$args[5] <= 0)
		return new IXR_Error(-40000, 'W3_InvalidTimestamp');

	// check proxy session
	if (false === fgsProxys::checkSession($args[0]))
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// update user infos
	$change = fgsUsers::updateEntries($args[1], $args[2], $args[3], $args[4], $args[5]);
	if ($change === false)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	return true;
}
// }}}

// {{{ method : fgsd.server.register()
// param 0 : fgsd_sid
// param 1 : game_name
// param 2 : game_version
// param 3 : game_port
function fgsd_server_register($args)
{
	// check parameter count
	if (count($args) != 4)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40014, 'W3_InvalidGameName');
	if (empty($args[2]))
		return new IXR_Error(-40014, 'W3_InvalidGameVersion');
	if (empty($args[3]))
		return new IXR_Error(-40014, 'W3_InvalidGamePort');

	// check proxy session
	$fgsd = fgsProxys::checkSession($args[0]);
	if (false === $fgsd)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// check game
	if (false == fgsGames::exist($args[1]))
		return new IXR_Error(-40000, 'W3_UnknownGameName');

	// register game
	$game_sid = fgsGames::register($fgsd, $args[1], $args[2], $args[3]);
	if (false === $game_sid)
		return new IXR_Error(-40000, 'W3_InternalError');

	return $game_sid;
}
// }}}

// {{{ method : fgsd.server.unregister()
// param 0 : fgsd_sid
// param 1 : game_sid
function fgsd_server_unregister($args)
{
	// check parameter count
	if (count($args) != 2)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40014, 'W3_InvalidGameSessionId');

	// check proxy session
	$fgsd = fgsProxys::checkSession($args[0]);
	if (false === $fgsd)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// unregister game
	if (false === fgsGames::unregister($fgsd, $args[1]))
		return new IXR_Error(-40000, 'W3_InternalError');

	return true;
}
// }}}

// {{{ method : fgsd.server.update()
// param 0 : fgsd_sid
// param 1 : game_sid
// param 2 : match_id
// param 3 : array: match_game
// param 4 : array: match_players
// param 5 : timestamp
function fgsd_server_update($args)
{
	// check parameter count
	if (count($args) != 6)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40014, 'W3_InvalidGameSessionId');
	if ((int)($args[2]) < 0)
		return new IXR_Error(-40014, 'W3_InvalidMatchId');
	if (!is_array($args[3]))
		return new IXR_Error(-40014, 'W3_InvalidMatchGame');
	if (!is_array($args[4]))
		return new IXR_Error(-40014, 'W3_InvalidMatchPlayers');
	if ((int)$args[5] <= 0)
		return new IXR_Error(-40000, 'W3_InvalidTimestamp');

	// search if fgsd and game is authorized
	$fgsd = fgsProxys::checkSessionWithGame($args[0], $args[1]);
	if (false === $fgsd)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	// update match
	$change = fgsMatchs::update($fgsd, $args[2], $args[3], $args[4], $args[5]); 
	if ($change === false)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	return true;
}
// }}}

// {{{ method : fgsd.server.lock()
// param 0 : fgsd_sid
// param 1 : game_sid
// param 2 : match_id
function fgsd_server_lock($args)
{
	// check parameter count
	if (count($args) != 3)
		return new IXR_Error(-40001, 'W3_InvalidParameterCount');

	// check parameters
	if (empty($args[0]))
		return new IXR_Error(-40008, 'W3_InvalidSessionId');
	if (empty($args[1]))
		return new IXR_Error(-40014, 'W3_InvalidGameSessionId');
	if ((int)($args[2]) < 0)
		return new IXR_Error(-40014, 'W3_InvalidMatchId');

	// search if fgsd and game is authorized
	$fgsd = fgsProxys::checkSessionWithGame($args[0], $args[1]);
	if (false === $fgsd)
		return new IXR_Error(-40000, 'W3_Unauthorized');

	if (false === fgsMatchs::lock($fgsd, $args[2]))
		return new IXR_Error(-40014, 'W3_InvalidMatchId');

	return true;
}
// }}}

//============================================================

$server = new ixr_server(array(
	'news.getcategorylist'          => 'news_getcategorylist',
	'news.getnewslist'              => 'news_getnewslist',
	'news.getcategorylogo'          => 'news_getcategorylogo',
	'news.getnewsitem'              => 'news_getnewsitem',
	'user.login'                    => 'user_login',
	'user.logout'                   => 'user_logout',
	'user.info'                     => 'user_info',
	'user.getgamelist'              => 'user_getgamelist',
	'user.getserverlist'            => 'user_getserverlist',
	'user.getgamelogo'              => 'user_getgamelogo',
	'fgsd.user.verify'              => 'fgsd_user_verify',
	'fgsd.user.join'                => 'fgsd_user_join',
	'fgsd.user.leave'               => 'fgsd_user_leave',
	'fgsd.user.update'              => 'fgsd_user_update',
	'fgsd.register'                 => 'fgsd_register',
	'fgsd.unregister'               => 'fgsd_unregister',
	'fgsd.server.register'          => 'fgsd_server_register',
	'fgsd.server.unregister'        => 'fgsd_server_unregister',
	'fgsd.server.update'            => 'fgsd_server_update',
	'fgsd.server.lock'              => 'fgsd_server_lock',
	'fgsd.ping'                     => 'fgsd_ping'
));

$server->serve();

?>
